package websocket.dao;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;

import websocket.constant.Config;
import websocket.pojo.Group;
import websocket.pojo.Users;

/**
 * 用户信息操作的DAOn层
 * 
 * @author zhc
 * 
 */
public class UsersDAO {

	private static final Logger logger = Logger.getLogger(UsersDAO.class
			.getName());

	/**
	 * 根据用户ID来获得一个用户的信息 使用的缓存
	 * 
	 * @param uid
	 *            用户ID
	 * @return
	 */
	public Users findUser(long uid) {
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		Query query = session.createQuery("from Users where uid=?");
		query.setLong(0, uid);
		query.setCacheable(true);
		Users user = null;
		try {
			user = (Users) query.uniqueResult();
		} catch (Exception e) {
			logger.error(e.getMessage());
		} finally {
			session.getTransaction().commit();
			session.close();
		}
		return user;
	}

	/**
	 * 根据用户ID来获得分组
	 * 
	 * @param uid
	 * @return
	 */
	@SuppressWarnings(value = { "unchecked" })
	public List<Group> getGroups(long uid) {
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		List<Group> groups = null;
		try {
			Query query = session.createQuery("from Group where uid=?")
					.setLong(0, uid);
			query.setCacheable(true);
			groups = query.list();
		} finally {
			session.getTransaction().commit();
			session.close();
		}
		return groups;
	}

	/**
	 * 根据分组ID来获得一个分组下所有的好友
	 * 
	 * @param gid
	 * @return
	 */
	@SuppressWarnings(value = { "unchecked" })
	public List<Users> getFriends(long gid) {
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		List<Users> friends = null;
		try {
			friends = session
					.createQuery(
							"select new Users(u.uid,u.mail,u.sex,u.nickname,u.online,u.icon,u.signature) from Users u,Friends f where f.fuid = u.uid and f.gid=? order by u.online DESC")
					.setLong(0, gid).list();
		} finally {
			session.getTransaction().commit();
			session.close();
		}
		return friends;
	}

	/**
	 * 更新用户在线状态
	 * 
	 * @param uid
	 * @param status
	 */
	public void updateStatus(long uid, int status) {
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		try {
			session.createQuery("update Users set online=? where uid=?")
					.setInteger(0, status).setLong(1, uid).executeUpdate();
		} finally {
			session.getTransaction().commit();
			session.close();
		}
	}

	/**
	 * 获得一个用户所有的在线好友
	 * 
	 * @param uid
	 * @return
	 */
	@SuppressWarnings(value = { "unchecked" })
	public List<Users> findOnlineFirends(long uid) {
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		List<Users> friends = null;
		try {
			friends = session
					.createQuery(
							"select new Users(u.uid,u.online) from Group g ,Friends f,Users u where g.id = f.gid and g.uid=? and f.fuid = u.uid and u.online=1 and u.uid<>? ")
					.setLong(0, uid).setLong(1, uid).list();
		} finally {
			session.getTransaction().commit();
			session.close();
		}
		return friends;
	}

	/**
	 * 校验邮箱是否已经注册
	 * 
	 * @param mail
	 * @return
	 */
	public boolean validateMail(String mail) {
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		try {
			Object val = session
					.createQuery("select mail from Users where mail=?")
					.setString(0, mail).setCacheable(true).uniqueResult();
			if (val == null) {
				return true;
			}
			return false;
		} finally {
			session.getTransaction().commit();
			session.close();
		}
	}

	public boolean persistence(Object po) {
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		try {
			session.saveOrUpdate(po);
			return true;
		} catch (Exception e) {
			logger.error(e.getMessage());
			return false;
		} finally {
			session.getTransaction().commit();
			session.close();
		}
	}

	/**
	 * 检测一个ID在USERS表中是否存在相同记录，存在返回true，否则返回false
	 * 
	 * @param uid
	 * @return
	 */
	public boolean uidExist(Long uid) {
		Session session = HibernateSessionFactory.getSession();
		Long id = null;
		try {
			id = (Long) session
					.createQuery("select uid from Users where uid=?")
					.setLong(0, uid).uniqueResult();
		} catch (Exception e) {
			logger.info(e.getMessage());
		} finally {
			session.close();
		}
		return id != null;
	}

	public Long getMaxId() {
		Session session = HibernateSessionFactory.getSession();
		Long id = 666666L;
		try {
			BigInteger bid = (BigInteger) session.createSQLQuery(
					"select max(uid) from _users").uniqueResult();
			if (bid != null)
				id = bid.longValue();
		} finally {
			session.close();
		}
		return id;
	}

	/**
	 * 根据用户ID和分组名称来获得分组ID
	 * 
	 * @param uid
	 * @param name
	 * @return
	 */
	public Group getGroupByName(Long uid, String name) {
		Session session = HibernateSessionFactory.getSession();
		Group group = null;
		try {
			group = (Group) session
					.createQuery("from Group where uid=? and groupname=?")
					.setLong(0, uid).setString(1, name).uniqueResult();
		} finally {
			session.close();
		}
		return group;
	}

	/**
	 * 根据UID或昵称来查找用户
	 * 
	 * @param condition
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Users> list(String condition, Integer page) {
		List<Users> list = new ArrayList<Users>();
		Session session = HibernateSessionFactory.getSession();
		try {
			Query query = session
					.createQuery("from Users where uid=? or nickname like ?")
					.setString(0, condition)
					.setString(1, "%" + condition + "%");
			query.setFirstResult((page - 1) * Config.SEARCH_SIZE);
			query.setMaxResults(Config.SEARCH_SIZE);
			list = query.list();
		} finally {
			session.close();
		}
		return list;
	}

	public Long getTotal(String condition) {
		Session session = HibernateSessionFactory.getSession();
		Long total = 0L;
		try {
			total = (Long) session
					.createQuery(
							"select count(uid) from Users where uid=? or nickname like ?")
					.setString(0, condition)
					.setString(1, "%" + condition + "%").uniqueResult();

		} finally {
			session.close();
		}
		return total;
	}

	/**
	 * 检测一个用户是否为另一个用户的好友，如果是则返回true,否则返回false
	 * 
	 * @param uid
	 *            用户ID
	 * @param fid
	 *            好友ID
	 * @return
	 */
	public boolean checkFriend(Long uid, Long fid) {
		Session session = HibernateSessionFactory.getSession();
		boolean exist = true;
		try {
			List<?> list = session
					.createQuery(
							"FROM Group g ,Friends f where g.id = f.gid and g.uid=? and f.fuid=?")
					.setLong(0, uid).setLong(1, fid).list();
			if (list == null || list.size() == 0) {
				exist = false;
			}
		} finally {
			session.close();
		}
		return exist;
	}

	public Long userCount() {
		Long count = 0L;
		Session session = HibernateSessionFactory.getSession();
		try {
			count = (Long) session.createQuery("select count(*) from Users")
					.uniqueResult();
		} finally {
			session.close();
		}
		return count;
	}
}
